{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "idadd-aJHZYe"
      },
      "source": [
        "**Providing Parkinson's Disease Rehabilitation suggestions using Gemini combined with Environmental Factors**\n",
        "\n",
        "Author: Yung-Chen Hsieh\n",
        "\n",
        "Affiliation: Pacific American School\n",
        "\n",
        "This notebook uses Google Earth Engine to calculate NDVI, NDWI, and NDBI environmental factors and exports the processed data to be further used in providing suggestions. It also calls the OpenWeatherMap APIs and NOAA geomagnetic data to obtain environmental information such as air quality, temperature, humidity, weather. These environmental information are provided along with the patients profile, which includes family disease history, lifestyle habits, etc, to be used to provide suggestions on how to improve patients' health. The information are provided to Gemini and Gemini is prompted to provide personal lifestyle recommendations.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oZ6wwFDLG4TP"
      },
      "source": [
        "Installs earthengine-api and geemap, authenticates with Google Earth Engine, and initializes the session to access remote sensing data."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "id": "YTwhhQrbENzV",
        "outputId": "f48b8f6c-f41f-4a2c-ef63-966bcd4cfe24"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Requirement already satisfied: earthengine-api in /usr/local/lib/python3.11/dist-packages (1.5.24)\n",
            "Requirement already satisfied: google-cloud-storage in /usr/local/lib/python3.11/dist-packages (from earthengine-api) (2.19.0)\n",
            "Requirement already satisfied: google-api-python-client>=1.12.1 in /usr/local/lib/python3.11/dist-packages (from earthengine-api) (2.177.0)\n",
            "Requirement already satisfied: google-auth>=1.4.1 in /usr/local/lib/python3.11/dist-packages (from earthengine-api) (2.38.0)\n",
            "Requirement already satisfied: google-auth-httplib2>=0.0.3 in /usr/local/lib/python3.11/dist-packages (from earthengine-api) (0.2.0)\n",
            "Requirement already satisfied: httplib2<1dev,>=0.9.2 in /usr/local/lib/python3.11/dist-packages (from earthengine-api) (0.22.0)\n",
            "Requirement already satisfied: requests in /usr/local/lib/python3.11/dist-packages (from earthengine-api) (2.32.3)\n",
            "Requirement already satisfied: google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5 in /usr/local/lib/python3.11/dist-packages (from google-api-python-client>=1.12.1->earthengine-api) (2.25.1)\n",
            "Requirement already satisfied: uritemplate<5,>=3.0.1 in /usr/local/lib/python3.11/dist-packages (from google-api-python-client>=1.12.1->earthengine-api) (4.2.0)\n",
            "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.11/dist-packages (from google-auth>=1.4.1->earthengine-api) (5.5.2)\n",
            "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.11/dist-packages (from google-auth>=1.4.1->earthengine-api) (0.4.2)\n",
            "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.11/dist-packages (from google-auth>=1.4.1->earthengine-api) (4.9.1)\n",
            "Requirement already satisfied: pyparsing!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3,<4,>=2.4.2 in /usr/local/lib/python3.11/dist-packages (from httplib2<1dev,>=0.9.2->earthengine-api) (3.2.3)\n",
            "Requirement already satisfied: google-cloud-core<3.0dev,>=2.3.0 in /usr/local/lib/python3.11/dist-packages (from google-cloud-storage->earthengine-api) (2.4.3)\n",
            "Requirement already satisfied: google-resumable-media>=2.7.2 in /usr/local/lib/python3.11/dist-packages (from google-cloud-storage->earthengine-api) (2.7.2)\n",
            "Requirement already satisfied: google-crc32c<2.0dev,>=1.0 in /usr/local/lib/python3.11/dist-packages (from google-cloud-storage->earthengine-api) (1.7.1)\n",
            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api) (3.4.2)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api) (3.10)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api) (2.5.0)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api) (2025.8.3)\n",
            "Requirement already satisfied: googleapis-common-protos<2.0.0,>=1.56.2 in /usr/local/lib/python3.11/dist-packages (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client>=1.12.1->earthengine-api) (1.70.0)\n",
            "Requirement already satisfied: protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.19.5 in /usr/local/lib/python3.11/dist-packages (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client>=1.12.1->earthengine-api) (5.29.5)\n",
            "Requirement already satisfied: proto-plus<2.0.0,>=1.22.3 in /usr/local/lib/python3.11/dist-packages (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client>=1.12.1->earthengine-api) (1.26.1)\n",
            "Requirement already satisfied: pyasn1<0.7.0,>=0.6.1 in /usr/local/lib/python3.11/dist-packages (from pyasn1-modules>=0.2.1->google-auth>=1.4.1->earthengine-api) (0.6.1)\n",
            "Requirement already satisfied: geemap in /usr/local/lib/python3.11/dist-packages (0.35.3)\n",
            "Requirement already satisfied: bqplot in /usr/local/lib/python3.11/dist-packages (from geemap) (0.12.45)\n",
            "Requirement already satisfied: colour in /usr/local/lib/python3.11/dist-packages (from geemap) (0.1.5)\n",
            "Requirement already satisfied: earthengine-api>=1.0.0 in /usr/local/lib/python3.11/dist-packages (from geemap) (1.5.24)\n",
            "Requirement already satisfied: eerepr>=0.1.0 in /usr/local/lib/python3.11/dist-packages (from geemap) (0.1.2)\n",
            "Requirement already satisfied: folium>=0.17.0 in /usr/local/lib/python3.11/dist-packages (from geemap) (0.20.0)\n",
            "Requirement already satisfied: geocoder in /usr/local/lib/python3.11/dist-packages (from geemap) (1.38.1)\n",
            "Requirement already satisfied: ipyevents in /usr/local/lib/python3.11/dist-packages (from geemap) (2.0.2)\n",
            "Requirement already satisfied: ipyfilechooser>=0.6.0 in /usr/local/lib/python3.11/dist-packages (from geemap) (0.6.0)\n",
            "Requirement already satisfied: ipyleaflet>=0.19.2 in /usr/local/lib/python3.11/dist-packages (from geemap) (0.20.0)\n",
            "Requirement already satisfied: ipytree in /usr/local/lib/python3.11/dist-packages (from geemap) (0.2.2)\n",
            "Requirement already satisfied: matplotlib in /usr/local/lib/python3.11/dist-packages (from geemap) (3.10.0)\n",
            "Requirement already satisfied: numpy in /usr/local/lib/python3.11/dist-packages (from geemap) (2.0.2)\n",
            "Requirement already satisfied: pandas in /usr/local/lib/python3.11/dist-packages (from geemap) (2.2.2)\n",
            "Requirement already satisfied: plotly in /usr/local/lib/python3.11/dist-packages (from geemap) (5.24.1)\n",
            "Requirement already satisfied: pyperclip in /usr/local/lib/python3.11/dist-packages (from geemap) (1.9.0)\n",
            "Requirement already satisfied: pyshp>=2.3.1 in /usr/local/lib/python3.11/dist-packages (from geemap) (2.3.1)\n",
            "Requirement already satisfied: python-box in /usr/local/lib/python3.11/dist-packages (from geemap) (7.3.2)\n",
            "Requirement already satisfied: scooby in /usr/local/lib/python3.11/dist-packages (from geemap) (0.10.1)\n",
            "Requirement already satisfied: google-cloud-storage in /usr/local/lib/python3.11/dist-packages (from earthengine-api>=1.0.0->geemap) (2.19.0)\n",
            "Requirement already satisfied: google-api-python-client>=1.12.1 in /usr/local/lib/python3.11/dist-packages (from earthengine-api>=1.0.0->geemap) (2.177.0)\n",
            "Requirement already satisfied: google-auth>=1.4.1 in /usr/local/lib/python3.11/dist-packages (from earthengine-api>=1.0.0->geemap) (2.38.0)\n",
            "Requirement already satisfied: google-auth-httplib2>=0.0.3 in /usr/local/lib/python3.11/dist-packages (from earthengine-api>=1.0.0->geemap) (0.2.0)\n",
            "Requirement already satisfied: httplib2<1dev,>=0.9.2 in /usr/local/lib/python3.11/dist-packages (from earthengine-api>=1.0.0->geemap) (0.22.0)\n",
            "Requirement already satisfied: requests in /usr/local/lib/python3.11/dist-packages (from earthengine-api>=1.0.0->geemap) (2.32.3)\n",
            "Requirement already satisfied: branca>=0.6.0 in /usr/local/lib/python3.11/dist-packages (from folium>=0.17.0->geemap) (0.8.1)\n",
            "Requirement already satisfied: jinja2>=2.9 in /usr/local/lib/python3.11/dist-packages (from folium>=0.17.0->geemap) (3.1.6)\n",
            "Requirement already satisfied: xyzservices in /usr/local/lib/python3.11/dist-packages (from folium>=0.17.0->geemap) (2025.4.0)\n",
            "Requirement already satisfied: ipywidgets in /usr/local/lib/python3.11/dist-packages (from ipyfilechooser>=0.6.0->geemap) (7.7.1)\n",
            "Requirement already satisfied: jupyter-leaflet<0.21,>=0.20 in /usr/local/lib/python3.11/dist-packages (from ipyleaflet>=0.19.2->geemap) (0.20.0)\n",
            "Requirement already satisfied: traittypes<3,>=0.2.1 in /usr/local/lib/python3.11/dist-packages (from ipyleaflet>=0.19.2->geemap) (0.2.1)\n",
            "Requirement already satisfied: traitlets>=4.3.0 in /usr/local/lib/python3.11/dist-packages (from bqplot->geemap) (5.7.1)\n",
            "Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.11/dist-packages (from pandas->geemap) (2.9.0.post0)\n",
            "Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.11/dist-packages (from pandas->geemap) (2025.2)\n",
            "Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.11/dist-packages (from pandas->geemap) (2025.2)\n",
            "Requirement already satisfied: click in /usr/local/lib/python3.11/dist-packages (from geocoder->geemap) (8.2.1)\n",
            "Requirement already satisfied: future in /usr/local/lib/python3.11/dist-packages (from geocoder->geemap) (1.0.0)\n",
            "Requirement already satisfied: ratelim in /usr/local/lib/python3.11/dist-packages (from geocoder->geemap) (0.1.6)\n",
            "Requirement already satisfied: six in /usr/local/lib/python3.11/dist-packages (from geocoder->geemap) (1.17.0)\n",
            "Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib->geemap) (1.3.3)\n",
            "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.11/dist-packages (from matplotlib->geemap) (0.12.1)\n",
            "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.11/dist-packages (from matplotlib->geemap) (4.59.0)\n",
            "Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib->geemap) (1.4.8)\n",
            "Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.11/dist-packages (from matplotlib->geemap) (25.0)\n",
            "Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.11/dist-packages (from matplotlib->geemap) (11.3.0)\n",
            "Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib->geemap) (3.2.3)\n",
            "Requirement already satisfied: tenacity>=6.2.0 in /usr/local/lib/python3.11/dist-packages (from plotly->geemap) (8.5.0)\n",
            "Requirement already satisfied: google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5 in /usr/local/lib/python3.11/dist-packages (from google-api-python-client>=1.12.1->earthengine-api>=1.0.0->geemap) (2.25.1)\n",
            "Requirement already satisfied: uritemplate<5,>=3.0.1 in /usr/local/lib/python3.11/dist-packages (from google-api-python-client>=1.12.1->earthengine-api>=1.0.0->geemap) (4.2.0)\n",
            "Requirement already satisfied: cachetools<6.0,>=2.0.0 in /usr/local/lib/python3.11/dist-packages (from google-auth>=1.4.1->earthengine-api>=1.0.0->geemap) (5.5.2)\n",
            "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.11/dist-packages (from google-auth>=1.4.1->earthengine-api>=1.0.0->geemap) (0.4.2)\n",
            "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.11/dist-packages (from google-auth>=1.4.1->earthengine-api>=1.0.0->geemap) (4.9.1)\n",
            "Requirement already satisfied: ipykernel>=4.5.1 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->ipyfilechooser>=0.6.0->geemap) (6.17.1)\n",
            "Requirement already satisfied: ipython-genutils~=0.2.0 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.2.0)\n",
            "Requirement already satisfied: widgetsnbextension~=3.6.0 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->ipyfilechooser>=0.6.0->geemap) (3.6.10)\n",
            "Requirement already satisfied: ipython>=4.0.0 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->ipyfilechooser>=0.6.0->geemap) (7.34.0)\n",
            "Requirement already satisfied: jupyterlab-widgets>=1.0.0 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->ipyfilechooser>=0.6.0->geemap) (3.0.15)\n",
            "Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.11/dist-packages (from jinja2>=2.9->folium>=0.17.0->geemap) (3.0.2)\n",
            "Requirement already satisfied: google-cloud-core<3.0dev,>=2.3.0 in /usr/local/lib/python3.11/dist-packages (from google-cloud-storage->earthengine-api>=1.0.0->geemap) (2.4.3)\n",
            "Requirement already satisfied: google-resumable-media>=2.7.2 in /usr/local/lib/python3.11/dist-packages (from google-cloud-storage->earthengine-api>=1.0.0->geemap) (2.7.2)\n",
            "Requirement already satisfied: google-crc32c<2.0dev,>=1.0 in /usr/local/lib/python3.11/dist-packages (from google-cloud-storage->earthengine-api>=1.0.0->geemap) (1.7.1)\n",
            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api>=1.0.0->geemap) (3.4.2)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api>=1.0.0->geemap) (3.10)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api>=1.0.0->geemap) (2.5.0)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/dist-packages (from requests->earthengine-api>=1.0.0->geemap) (2025.8.3)\n",
            "Requirement already satisfied: decorator in /usr/local/lib/python3.11/dist-packages (from ratelim->geocoder->geemap) (4.4.2)\n",
            "Requirement already satisfied: googleapis-common-protos<2.0.0,>=1.56.2 in /usr/local/lib/python3.11/dist-packages (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client>=1.12.1->earthengine-api>=1.0.0->geemap) (1.70.0)\n",
            "Requirement already satisfied: protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.19.5 in /usr/local/lib/python3.11/dist-packages (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client>=1.12.1->earthengine-api>=1.0.0->geemap) (5.29.5)\n",
            "Requirement already satisfied: proto-plus<2.0.0,>=1.22.3 in /usr/local/lib/python3.11/dist-packages (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client>=1.12.1->earthengine-api>=1.0.0->geemap) (1.26.1)\n",
            "Requirement already satisfied: debugpy>=1.0 in /usr/local/lib/python3.11/dist-packages (from ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.8.15)\n",
            "Requirement already satisfied: jupyter-client>=6.1.12 in /usr/local/lib/python3.11/dist-packages (from ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (6.1.12)\n",
            "Requirement already satisfied: matplotlib-inline>=0.1 in /usr/local/lib/python3.11/dist-packages (from ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.1.7)\n",
            "Requirement already satisfied: nest-asyncio in /usr/local/lib/python3.11/dist-packages (from ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.6.0)\n",
            "Requirement already satisfied: psutil in /usr/local/lib/python3.11/dist-packages (from ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (5.9.5)\n",
            "Requirement already satisfied: pyzmq>=17 in /usr/local/lib/python3.11/dist-packages (from ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (26.2.1)\n",
            "Requirement already satisfied: tornado>=6.1 in /usr/local/lib/python3.11/dist-packages (from ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (6.4.2)\n",
            "Requirement already satisfied: setuptools>=18.5 in /usr/local/lib/python3.11/dist-packages (from ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (75.2.0)\n",
            "Collecting jedi>=0.16 (from ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap)\n",
            "  Downloading jedi-0.19.2-py2.py3-none-any.whl.metadata (22 kB)\n",
            "Requirement already satisfied: pickleshare in /usr/local/lib/python3.11/dist-packages (from ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.7.5)\n",
            "Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /usr/local/lib/python3.11/dist-packages (from ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (3.0.51)\n",
            "Requirement already satisfied: pygments in /usr/local/lib/python3.11/dist-packages (from ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (2.19.2)\n",
            "Requirement already satisfied: backcall in /usr/local/lib/python3.11/dist-packages (from ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.2.0)\n",
            "Requirement already satisfied: pexpect>4.3 in /usr/local/lib/python3.11/dist-packages (from ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (4.9.0)\n",
            "Requirement already satisfied: pyasn1<0.7.0,>=0.6.1 in /usr/local/lib/python3.11/dist-packages (from pyasn1-modules>=0.2.1->google-auth>=1.4.1->earthengine-api>=1.0.0->geemap) (0.6.1)\n",
            "Requirement already satisfied: notebook>=4.4.1 in /usr/local/lib/python3.11/dist-packages (from widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (6.5.7)\n",
            "Requirement already satisfied: parso<0.9.0,>=0.8.4 in /usr/local/lib/python3.11/dist-packages (from jedi>=0.16->ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.8.4)\n",
            "Requirement already satisfied: jupyter-core>=4.6.0 in /usr/local/lib/python3.11/dist-packages (from jupyter-client>=6.1.12->ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (5.8.1)\n",
            "Requirement already satisfied: argon2-cffi in /usr/local/lib/python3.11/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (25.1.0)\n",
            "Requirement already satisfied: nbformat in /usr/local/lib/python3.11/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (5.10.4)\n",
            "Requirement already satisfied: nbconvert>=5 in /usr/local/lib/python3.11/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (7.16.6)\n",
            "Requirement already satisfied: Send2Trash>=1.8.0 in /usr/local/lib/python3.11/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.8.3)\n",
            "Requirement already satisfied: terminado>=0.8.3 in /usr/local/lib/python3.11/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.18.1)\n",
            "Requirement already satisfied: prometheus-client in /usr/local/lib/python3.11/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.22.1)\n",
            "Requirement already satisfied: nbclassic>=0.4.7 in /usr/local/lib/python3.11/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.3.1)\n",
            "Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.11/dist-packages (from pexpect>4.3->ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.7.0)\n",
            "Requirement already satisfied: wcwidth in /usr/local/lib/python3.11/dist-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython>=4.0.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.2.13)\n",
            "Requirement already satisfied: platformdirs>=2.5 in /usr/local/lib/python3.11/dist-packages (from jupyter-core>=4.6.0->jupyter-client>=6.1.12->ipykernel>=4.5.1->ipywidgets->ipyfilechooser>=0.6.0->geemap) (4.3.8)\n",
            "Requirement already satisfied: notebook-shim>=0.2.3 in /usr/local/lib/python3.11/dist-packages (from nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.2.4)\n",
            "Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.11/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (4.13.4)\n",
            "Requirement already satisfied: bleach!=5.0.0 in /usr/local/lib/python3.11/dist-packages (from bleach[css]!=5.0.0->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (6.2.0)\n",
            "Requirement already satisfied: defusedxml in /usr/local/lib/python3.11/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.7.1)\n",
            "Requirement already satisfied: jupyterlab-pygments in /usr/local/lib/python3.11/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.3.0)\n",
            "Requirement already satisfied: mistune<4,>=2.0.3 in /usr/local/lib/python3.11/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (3.1.3)\n",
            "Requirement already satisfied: nbclient>=0.5.0 in /usr/local/lib/python3.11/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.10.2)\n",
            "Requirement already satisfied: pandocfilters>=1.4.1 in /usr/local/lib/python3.11/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.5.1)\n",
            "Requirement already satisfied: fastjsonschema>=2.15 in /usr/local/lib/python3.11/dist-packages (from nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (2.21.1)\n",
            "Requirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.11/dist-packages (from nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (4.25.0)\n",
            "Requirement already satisfied: argon2-cffi-bindings in /usr/local/lib/python3.11/dist-packages (from argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (25.1.0)\n",
            "Requirement already satisfied: webencodings in /usr/local/lib/python3.11/dist-packages (from bleach!=5.0.0->bleach[css]!=5.0.0->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.5.1)\n",
            "Requirement already satisfied: tinycss2<1.5,>=1.1.0 in /usr/local/lib/python3.11/dist-packages (from bleach[css]!=5.0.0->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.4.0)\n",
            "Requirement already satisfied: attrs>=22.2.0 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (25.3.0)\n",
            "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (2025.4.1)\n",
            "Requirement already satisfied: referencing>=0.28.4 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.36.2)\n",
            "Requirement already satisfied: rpds-py>=0.7.1 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (0.26.0)\n",
            "Requirement already satisfied: jupyter-server<3,>=1.8 in /usr/local/lib/python3.11/dist-packages (from notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.16.0)\n",
            "Requirement already satisfied: cffi>=1.0.1 in /usr/local/lib/python3.11/dist-packages (from argon2-cffi-bindings->argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.17.1)\n",
            "Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (2.7)\n",
            "Requirement already satisfied: typing-extensions>=4.0.0 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (4.14.1)\n",
            "Requirement already satisfied: pycparser in /usr/local/lib/python3.11/dist-packages (from cffi>=1.0.1->argon2-cffi-bindings->argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (2.22)\n",
            "Requirement already satisfied: anyio>=3.1.0 in /usr/local/lib/python3.11/dist-packages (from jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (4.10.0)\n",
            "Requirement already satisfied: websocket-client in /usr/local/lib/python3.11/dist-packages (from jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.8.0)\n",
            "Requirement already satisfied: sniffio>=1.1 in /usr/local/lib/python3.11/dist-packages (from anyio>=3.1.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets->ipyfilechooser>=0.6.0->geemap) (1.3.1)\n",
            "Downloading jedi-0.19.2-py2.py3-none-any.whl (1.6 MB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m23.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hInstalling collected packages: jedi\n",
            "Successfully installed jedi-0.19.2\n"
          ]
        }
      ],
      "source": [
        "!pip install earthengine-api\n",
        "!pip install geemap\n",
        "import ee\n",
        "import geemap"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "58mfaiqWGYwy",
        "outputId": "4ef901a3-9dbc-46a0-8e27-0ddadfdc5ca8"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "ee.Authenticate()\n",
        "geemap.ee_initialize(project='environment-462011-c5')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lN6hWjb6HJaz"
      },
      "source": [
        "Define the analysis period (June–December 2024), filter Sentinel-2 imagery to remove scenes with >10% cloud cover"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "PY2JPTBxGhpB",
        "outputId": "eecbb97d-2e88-4ce7-a003-8822ba8c1a43"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# define the time frame\n",
        "start_date = '2024-06-01'\n",
        "end_date = '2024-12-31'\n",
        "\n",
        "# obtain Sentinel-2 data, remove cloudyPercentage>10%\n",
        "collection = ee.ImageCollection('COPERNICUS/S2_HARMONIZED') \\\n",
        "    .filterDate(start_date, end_date) \\\n",
        "    .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10)) \\\n",
        "    .median()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "hyQcX8l-HqCj"
      },
      "source": [
        "Computes vegetation, water, and built-up indices and applies color palettes for visualization."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "TMo813pxGkA-",
        "outputId": "9d98d6d4-6ece-4def-8e4e-72a89702c95a"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# calculate NDVI、NDWI、NDBI\n",
        "ndvi = collection.normalizedDifference(['B8', 'B4']).rename('NDVI')\n",
        "ndwi = collection.normalizedDifference(['B3', 'B8']).rename('NDWI')\n",
        "ndbi = collection.normalizedDifference(['B11', 'B8']).rename('NDBI')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "C81LtI7RGntD",
        "outputId": "7691c3d2-b054-4d3e-9e7c-27655844be1f"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Apply a color palette to visualize the indices as RGB images\n",
        "# You can adjust the min/max values and the colors as needed\n",
        "ndvi_rgb = ndvi.visualize(min=-1, max=1, palette=['red', 'yellow', 'green'])\n",
        "ndwi_rgb = ndwi.visualize(min=0, max=1, palette=['0000ff', '00ffff', 'ffff00', 'ff0000', 'ffffff']) # Example NDWI palette\n",
        "ndbi_rgb = ndbi.visualize(min=-1, max=1, palette=['0a1f3a', '1d2b4b', '30385b', '43456b', '57527b', '6a5f8b', '7d6c9b', '9079ab', 'a386bb', 'b693cb', 'c9a0db', 'dcbde0', 'efcaef', 'ffffff']) # Example NDBI palette"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_3_pDVr-H8nR"
      },
      "source": [
        "Specify geographic regions, projection scale, and exports the NDVI/NDWI/NDBI results to Google Drive for future use."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "X_E1EqxkG9Jn",
        "outputId": "eec77896-a221-47fa-a14f-d519e4fe7827"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# define the region\n",
        "us_region = ee.Geometry.Rectangle([-125, 24, -66.5, 49])\n",
        "taiwan_region = ee.Geometry.Rectangle([119.3, 21.8, 122.5, 25.4])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "5Y7qT9iaHA9Q",
        "outputId": "63287b50-b797-472f-8653-7e5d96c5ea53"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "scale = 500\n",
        "crs = 'EPSG:4326'\n",
        "folder = 'EarthEngine'"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "iPxXXMJPHDXY",
        "outputId": "3fa6174f-fc87-4c07-d03d-0154fdbb7102"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# NDVI\n",
        "task_ndvi = ee.batch.Export.image.toDrive(\n",
        "    image=ndvi_rgb,\n",
        "    description='NDVI_TW_2024',\n",
        "    folder=folder,\n",
        "    fileNamePrefix='NDVI_TW_2024',\n",
        "    region=taiwan_region,\n",
        "    scale=scale,\n",
        "    crs=crs,\n",
        "    maxPixels=1e13\n",
        ")\n",
        "task_ndvi.start()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "5qEHr-QhHIkL",
        "outputId": "518255d7-0930-4790-e7b6-c46ec46f2ebc"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# NDWI\n",
        "task_ndwi = ee.batch.Export.image.toDrive(\n",
        "    image=ndwi_rgb,\n",
        "    description='NDWI_TW_2024',\n",
        "    folder=folder,\n",
        "    fileNamePrefix='NDWI_TW_2024',\n",
        "    region=taiwan_region,\n",
        "    scale=scale,\n",
        "    crs=crs,\n",
        "    maxPixels=1e13\n",
        ")\n",
        "task_ndwi.start()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "2q3f30_hHKZj",
        "outputId": "f2446097-5d76-4283-df23-bb105b19f7e7"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# NDBI\n",
        "task_ndbi = ee.batch.Export.image.toDrive(\n",
        "    image=ndbi_rgb,\n",
        "    description='NDBI_TW_2024',\n",
        "    folder=folder,\n",
        "    fileNamePrefix='NDBI_TW_2024',\n",
        "    region=taiwan_region,\n",
        "    scale=scale,\n",
        "    crs=crs,\n",
        "    maxPixels=1e13\n",
        ")\n",
        "task_ndbi.start()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "omwfFmQ1IOO9"
      },
      "source": [
        "Download the NDBI, NDVI, and NDWI files to be used to collect environmental information"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "ABrRdhQSIRIl",
        "outputId": "28e99821-cfcf-4b34-ff71-5e249c5d5f9f"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "!pip install -q gdown"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 303
        },
        "id": "S4XvqG1rIZmg",
        "outputId": "4e75461a-fd8f-496c-cb73-859836c51f6a"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Downloading NDBI from Google Drive...\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Downloading...\n",
            "From: https://drive.google.com/uc?id=1AezsL8xUngQWuAbN2uVwBR07nu3dEmOz\n",
            "To: /content/NDBI.tif\n",
            "100%|██████████| 787k/787k [00:00<00:00, 125MB/s]\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Downloading NDVI from Google Drive...\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Downloading...\n",
            "From: https://drive.google.com/uc?id=1w5mpGXK-f7hJx08t-bEHrEq2IxQpetfq\n",
            "To: /content/NDVI.tif\n",
            "100%|██████████| 683k/683k [00:00<00:00, 109MB/s]\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Downloading NDWI from Google Drive...\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Downloading...\n",
            "From: https://drive.google.com/uc?id=1Y8l0fXJhdqVwL56vchHFTFO45AlnTsq8\n",
            "To: /content/NDWI.tif\n",
            "100%|██████████| 745k/745k [00:00<00:00, 112MB/s]"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Finished Downloading\n"
          ]
        },
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "\n"
          ]
        }
      ],
      "source": [
        "import gdown\n",
        "\n",
        "files = {\n",
        "    \"NDBI\": \"1AezsL8xUngQWuAbN2uVwBR07nu3dEmOz\",\n",
        "    \"NDVI\": \"1w5mpGXK-f7hJx08t-bEHrEq2IxQpetfq\",\n",
        "    \"NDWI\": \"1Y8l0fXJhdqVwL56vchHFTFO45AlnTsq8\",\n",
        "}\n",
        "# download the NDBI, NDVI, NDWI documents\n",
        "for name, file_id in files.items():\n",
        "    url = f\"https://drive.google.com/uc?id={file_id}\"\n",
        "    output = f\"{name}.tif\"\n",
        "    print(f\"Downloading {name} from Google Drive...\")\n",
        "    gdown.download(url, output, quiet=False)\n",
        "\n",
        "print(\"Finished Downloading\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 106
        },
        "id": "KXYog-aghG3d",
        "outputId": "b7dcefd8-721d-4dda-8de7-acb4760f03ed"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Collecting geojson\n",
            "  Downloading geojson-3.2.0-py3-none-any.whl.metadata (16 kB)\n",
            "Downloading geojson-3.2.0-py3-none-any.whl (15 kB)\n",
            "Installing collected packages: geojson\n",
            "Successfully installed geojson-3.2.0\n"
          ]
        }
      ],
      "source": [
        "!pip install geojson"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 410
        },
        "id": "eHLZCH3Bhu5T",
        "outputId": "ad525181-3b1d-449e-cf2a-2d5c764900f8"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Requirement already satisfied: geojson in /usr/local/lib/python3.11/dist-packages (3.2.0)\n",
            "Collecting rasterio\n",
            "  Downloading rasterio-1.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (9.1 kB)\n",
            "Requirement already satisfied: shapely in /usr/local/lib/python3.11/dist-packages (2.1.1)\n",
            "Requirement already satisfied: numpy in /usr/local/lib/python3.11/dist-packages (2.0.2)\n",
            "Collecting affine (from rasterio)\n",
            "  Downloading affine-2.4.0-py3-none-any.whl.metadata (4.0 kB)\n",
            "Requirement already satisfied: attrs in /usr/local/lib/python3.11/dist-packages (from rasterio) (25.3.0)\n",
            "Requirement already satisfied: certifi in /usr/local/lib/python3.11/dist-packages (from rasterio) (2025.8.3)\n",
            "Requirement already satisfied: click>=4.0 in /usr/local/lib/python3.11/dist-packages (from rasterio) (8.2.1)\n",
            "Collecting cligj>=0.5 (from rasterio)\n",
            "  Downloading cligj-0.7.2-py3-none-any.whl.metadata (5.0 kB)\n",
            "Collecting click-plugins (from rasterio)\n",
            "  Downloading click_plugins-1.1.1.2-py2.py3-none-any.whl.metadata (6.5 kB)\n",
            "Requirement already satisfied: pyparsing in /usr/local/lib/python3.11/dist-packages (from rasterio) (3.2.3)\n",
            "Downloading rasterio-1.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (22.2 MB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m22.2/22.2 MB\u001b[0m \u001b[31m79.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hDownloading cligj-0.7.2-py3-none-any.whl (7.1 kB)\n",
            "Downloading affine-2.4.0-py3-none-any.whl (15 kB)\n",
            "Downloading click_plugins-1.1.1.2-py2.py3-none-any.whl (11 kB)\n",
            "Installing collected packages: cligj, click-plugins, affine, rasterio\n",
            "Successfully installed affine-2.4.0 click-plugins-1.1.1.2 cligj-0.7.2 rasterio-1.4.3\n"
          ]
        }
      ],
      "source": [
        "!pip install geojson rasterio shapely numpy"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 231
        },
        "id": "TdjtNouCh3Jg",
        "outputId": "3980b4e8-1a10-40c7-c79d-a7b3585e82c3"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Collecting dotenv\n",
            "  Downloading dotenv-0.9.9-py2.py3-none-any.whl.metadata (279 bytes)\n",
            "Collecting ephem\n",
            "  Downloading ephem-4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.1 kB)\n",
            "Collecting python-dotenv (from dotenv)\n",
            "  Downloading python_dotenv-1.1.1-py3-none-any.whl.metadata (24 kB)\n",
            "Downloading dotenv-0.9.9-py2.py3-none-any.whl (1.9 kB)\n",
            "Downloading ephem-4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.8/1.8 MB\u001b[0m \u001b[31m24.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hDownloading python_dotenv-1.1.1-py3-none-any.whl (20 kB)\n",
            "Installing collected packages: ephem, python-dotenv, dotenv\n",
            "Successfully installed dotenv-0.9.9 ephem-4.2 python-dotenv-1.1.1\n"
          ]
        }
      ],
      "source": [
        "!pip install dotenv ephem"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wULmjhx3KFXN"
      },
      "source": [
        "Defines a class to fetch environmental information such as weather, humidity, air quality, location context, etc. The processed environmental data is outputted in a dictionary for later use in providing recommendations."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "QUIdwdgqIp54",
        "outputId": "d990c5ee-9b42-4dad-cea9-a3f0c6fd7ca7"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import time\n",
        "from typing import Dict, Tuple\n",
        "from enum import Enum\n",
        "import geojson\n",
        "from shapely.geometry import Point\n",
        "import rasterio\n",
        "from rasterio.mask import mask\n",
        "import numpy as np\n",
        "import requests\n",
        "import os\n",
        "from dotenv import load_dotenv\n",
        "from datetime import datetime, timedelta\n",
        "from xml.etree import ElementTree\n",
        "import calendar\n",
        "import ephem\n",
        "\n",
        "\n",
        "\n",
        "\n",
        "class GeometryType(Enum):\n",
        "    CIRCLE = \"circle\"\n",
        "\n",
        "\n",
        "class EnvironmentIndexAPI:\n",
        "    # initialize file paths and API keys\n",
        "    def __init__(self, ndvi_source: str, ndwi_source: str, ndbi_source: str, geomagnetic_api_key: str):\n",
        "        self.ndvi_source = ndvi_source\n",
        "        self.ndwi_source = ndwi_source\n",
        "        self.ndbi_source = ndbi_source\n",
        "\n",
        "        self.weather_api_key = \"API Key\"\n",
        "        self.weather_api_base = \"https://api.openweathermap.org/data/2.5\"\n",
        "        self.geomagnetic_api_key = geomagnetic_api_key\n",
        "\n",
        "    # get the environmental information from a specific location and put the information into a dictionary\n",
        "    def get_environmental_info(self, coordinates, day_time, radius=1000, geometry_type=GeometryType.CIRCLE,\n",
        "                               elevation=0):\n",
        "        geometry = self._create_circle_geometry(coordinates, radius)\n",
        "\n",
        "        ndvi_stats = self._get_raster_stats(self.ndvi_source, geometry)\n",
        "        ndwi_stats = self._get_raster_stats(self.ndwi_source, geometry)\n",
        "        ndbi_stats = self._get_raster_stats(self.ndbi_source, geometry)\n",
        "        weather_data = self._get_weather_data(coordinates)\n",
        "        air_quality_data = self._get_air_quality_data(coordinates)\n",
        "        geomagnetic_data = self._get_geomagnetic_data(coordinates[0], coordinates[1], self.geomagnetic_api_key,\n",
        "                                                      elevation)\n",
        "        location_context = self._get_location_context(coordinates)\n",
        "\n",
        "        results = {\n",
        "            'location_context': location_context,\n",
        "            \"weather\": weather_data,\n",
        "            'ndvi': {\n",
        "                **ndvi_stats,\n",
        "                'level': self._ndvi_level(ndvi_stats.get('mean'))\n",
        "            },\n",
        "            'ndwi': {\n",
        "                **ndwi_stats,\n",
        "                'level': self._ndwi_level(ndwi_stats.get('mean'))\n",
        "            },\n",
        "            'ndbi': {\n",
        "                **ndbi_stats,\n",
        "                'level': self._ndbi_level(ndbi_stats.get('mean'))\n",
        "            },\n",
        "\n",
        "            'air_quality': air_quality_data,\n",
        "            'geomagnetic': {\n",
        "                **geomagnetic_data,\n",
        "                'stability': self._geomagnetic_stability(geomagnetic_data.get('declination_sv_deg_per_year'))\n",
        "            },\n",
        "            'time_context': self._get_time_category(coordinates, day_time)\n",
        "        }\n",
        "\n",
        "        return results\n",
        "\n",
        "    # create a circle around a particular point\n",
        "    def _create_circle_geometry(self, center: Tuple[float, float], radius: float) -> Dict:\n",
        "        point = Point(center[1], center[0])\n",
        "        circle = point.buffer(radius / 111320)\n",
        "        return geojson.Feature(geometry=circle, properties={})\n",
        "\n",
        "    # computes the mean, max, min of values in the circle\n",
        "    def _get_raster_stats(self, raster_path: str, geometry: Dict) -> Dict:\n",
        "        try:\n",
        "            with rasterio.open(raster_path) as src:\n",
        "                out_image, _ = mask(src, [geometry['geometry']], crop=True)\n",
        "                values = out_image[0]\n",
        "                return {\n",
        "                    'mean': float(np.nanmean(values)),\n",
        "                    'max': float(np.nanmax(values)),\n",
        "                    'min': float(np.nanmin(values))\n",
        "                }\n",
        "        except Exception as e:\n",
        "            return {'error': str(e)}\n",
        "\n",
        "    # Get weather data from OpenweatherMap\n",
        "    def _get_weather_data(self, coords):\n",
        "        try:\n",
        "            url = (\n",
        "                f\"https://api.openweathermap.org/data/2.5/weather\"\n",
        "                f\"?lat={coords[0]}&lon={coords[1]}&appid={self.weather_api_key}&units=metric\"\n",
        "            )\n",
        "            response = requests.get(url)\n",
        "            data = response.json()\n",
        "\n",
        "            temperature = data.get(\"main\", {}).get(\"temp\")\n",
        "            humidity = data.get(\"main\", {}).get(\"humidity\")\n",
        "            pressure = data.get(\"main\", {}).get(\"pressure\")  # air pressure\n",
        "            visibility = data.get(\"visibility\")  # visibility\n",
        "            wind_speed = data.get(\"wind\", {}).get(\"speed\")  #wind speed\n",
        "            wind_deg = data.get(\"wind\", {}).get(\"deg\")  # wind direction\n",
        "            wind_dir = self._wind_direction_from_deg(wind_deg) if wind_deg is not None else None\n",
        "            weather_desc = data.get(\"weather\", [{}])[0].get(\"description\")\n",
        "            wind_info = f\"{wind_dir}({wind_deg})\"\n",
        "\n",
        "            return {\n",
        "                \"temperature\": round(float(temperature), 2) if temperature is not None else None,\n",
        "                \"humidity\": round(float(humidity), 2) if humidity is not None else None,\n",
        "                \"pressure\": round(float(pressure), 2) if pressure is not None else None,\n",
        "                \"visibility_m\": visibility,\n",
        "                \"wind_speed_m_s\": round(float(wind_speed), 2) if wind_speed is not None else None,\n",
        "                \"wind_deg and direction\": wind_info,\n",
        "                \"weather_description\": weather_desc\n",
        "            }\n",
        "        except Exception as e:\n",
        "            print(f\"Error getting current weather: {e}\")\n",
        "            return None\n",
        "\n",
        "    # Get air quality data from OpenWeatherMap\n",
        "    def _get_air_quality_data(self, coords):\n",
        "\n",
        "        url = (\n",
        "            f\"https://api.openweathermap.org/data/2.5/air_pollution\"\n",
        "            f\"?lat={coords[0]}&lon={coords[1]}&appid={self.weather_api_key}\"\n",
        "        )\n",
        "        response = requests.get(url)\n",
        "        data = response.json()\n",
        "\n",
        "        aqi_index = data.get(\"list\", [{}])[0].get(\"main\", {}).get(\"aqi\")\n",
        "        components = data.get(\"list\", [{}])[0].get(\"components\", {})\n",
        "        pm2_5 = components.get(\"pm2_5\")\n",
        "        pm10 = components.get(\"pm10\")\n",
        "\n",
        "        return {\n",
        "            \"pm2_5\": round(float(pm2_5), 2) if pm2_5 is not None else None,\n",
        "            \"pm10\": round(float(pm10), 2) if pm10 is not None else None,\n",
        "            \"aqi_level\": aqi_index\n",
        "        }\n",
        "\n",
        "    # get geomagnetic data from NOAA\n",
        "    def _get_geomagnetic_data(self, lat: float, lon: float, api_key: str, elevation: float) -> Dict:\n",
        "        timestamp = datetime.utcnow().strftime(\"%Y-%m-%d\")\n",
        "\n",
        "        url = (\n",
        "            f\"https://www.ngdc.noaa.gov/geomag-web/calculators/calculateIgrfgrid?\"\n",
        "            f\"lat1={lat}&lat2={lat}&lon1={lon}&lon2={lon}&latStepSize=0.1&lonStepSize=0.1\"\n",
        "            f\"&magneticComponent=d&key={api_key}&date={timestamp}&elevation={elevation}\"\n",
        "        )\n",
        "\n",
        "        try:\n",
        "            response = requests.get(url)\n",
        "            response.raise_for_status()  # 加入状态码检查\n",
        "            root = ElementTree.fromstring(response.text)\n",
        "\n",
        "            result = root.find(\".//result\")\n",
        "            if result is None:\n",
        "                return {\"error\": \"No <result> element in response\"}\n",
        "\n",
        "            def get_text(tag):\n",
        "                el = result.find(f\".//{tag}\")\n",
        "                return el.text.strip() if el is not None else None\n",
        "\n",
        "            return {\n",
        "                \"elevation_km\": get_text(\"elevation\"),\n",
        "                \"declination_deg\": get_text(\"declination\"),\n",
        "                \"declination_sv_deg_per_year\": get_text(\"declination_sv\"),\n",
        "                \"declination_uncertainty_deg\": get_text(\"declination_uncertainty\")\n",
        "            }\n",
        "\n",
        "        except Exception as e:\n",
        "            return {\"error\": str(e)}\n",
        "\n",
        "    def _get_latest_humidity(self, coords):\n",
        "        try:\n",
        "            url = (\n",
        "                f\"https://api.openweathermap.org/data/2.5/weather?lat={coords[0]}&lon={coords[1]}\"\n",
        "                f\"&appid={self.weather_api_key}&units=metric\"\n",
        "            )\n",
        "            response = requests.get(url)\n",
        "            data = response.json()\n",
        "            humidity = data.get(\"main\", {}).get(\"humidity\")\n",
        "            return float(humidity) if humidity is not None else None\n",
        "        except:\n",
        "            return None\n",
        "\n",
        "    def _get_location_context(self, coordinates: Tuple[float, float]) -> str:\n",
        "        lat, lon = coordinates\n",
        "        try:\n",
        "            url = f\"https://nominatim.openstreetmap.org/reverse?format=json&lat={lat}&lon={lon}&zoom=18&addressdetails=1\"\n",
        "            response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'})\n",
        "            data = response.json()\n",
        "\n",
        "            type_str = data.get(\"type\", \"Unknown\")\n",
        "            category = data.get(\"category\", \"Unknown\")\n",
        "            display_name = data.get(\"display_name\", \"Unknown location\")\n",
        "            result_info = f\"Location information: {type_str}\\n  Category: {category}\\n  Detailed: {display_name}\"\n",
        "\n",
        "            return result_info\n",
        "\n",
        "        except Exception as e:\n",
        "            return \"Location information: Unknown\\nCategory:Unknown\\nUnknown location\"\n",
        "\n",
        "    def _get_time_category(self, coordinates: Tuple[float, float], dt_str: str) -> Dict:\n",
        "        try:\n",
        "            lat, lon = coordinates\n",
        "            date_obj = datetime.strptime(dt_str, \"%Y-%m-%dT%H:%M:%S\")\n",
        "\n",
        "            observer = ephem.Observer()\n",
        "            observer.lat = str(lat)\n",
        "            observer.lon = str(lon)\n",
        "            observer.date = date_obj\n",
        "\n",
        "            sun = ephem.Sun()\n",
        "            moon = ephem.Moon()\n",
        "\n",
        "            sunrise = observer.next_rising(sun).datetime()\n",
        "            sunset = observer.next_setting(sun).datetime()\n",
        "\n",
        "            if sunset < sunrise:\n",
        "                sunset += timedelta(days=1)\n",
        "\n",
        "            daylight_duration = sunset - sunrise\n",
        "\n",
        "            weekday = date_obj.strftime('%A')\n",
        "\n",
        "            moon.compute(observer)\n",
        "            phase = moon.phase\n",
        "            if phase < 10:\n",
        "                moon_phase = \"New Moon\"\n",
        "            elif 40 < phase < 60:\n",
        "                moon_phase = \"First Quarter\" if moon.elong < 0 else \"Last Quarter\"\n",
        "            elif 90 < phase < 100:\n",
        "                moon_phase = \"Full Moon\"\n",
        "            else:\n",
        "                moon_phase = \"Intermediate\"\n",
        "\n",
        "            return {\n",
        "                \"daylight_duration\": str(daylight_duration),\n",
        "                \"weekday\": weekday,\n",
        "                \"moon_phase\": moon_phase\n",
        "            }\n",
        "\n",
        "        except Exception as e:\n",
        "            return {\"error\": str(e)}\n",
        "\n",
        "    # convert NDVI, NDWI, NDBI into qualitative levels\n",
        "    def _ndvi_level(self, value):\n",
        "        if value is None:\n",
        "            return \"Unknown\"\n",
        "        if value > 0.5:\n",
        "            return \"High\"\n",
        "        elif value > 0.2:\n",
        "            return \"Medium\"\n",
        "        else:\n",
        "            return \"Low\"\n",
        "\n",
        "    def _ndwi_level(self, value):\n",
        "        if value is None:\n",
        "            return \"Unknown\"\n",
        "        if value > 0.3:\n",
        "            return \"Wet\"\n",
        "        elif value < 0:\n",
        "            return \"Dry\"\n",
        "        else:\n",
        "            return \"Neutral\"\n",
        "\n",
        "    def _ndbi_level(self, value):\n",
        "        if value is None:\n",
        "            return \"Unknown\"\n",
        "        if value > 0.2:\n",
        "            return \"Dense\"\n",
        "        elif value > 0:\n",
        "            return \"Moderate\"\n",
        "        else:\n",
        "            return \"Sparse\"\n",
        "\n",
        "    def _geomagnetic_stability(self, declination_sv):\n",
        "        try:\n",
        "            if declination_sv is None:\n",
        "                return \"Unknown\"\n",
        "            if float(declination_sv) > 0.1:\n",
        "                return \"Unstable\"\n",
        "            else:\n",
        "                return \"Stable\"\n",
        "        except:\n",
        "            return \"Unknown\"\n",
        "\n",
        "    def _wind_direction_from_deg(self, deg: float) -> str:\n",
        "        directions = [\n",
        "            \"North\", \"North-Northeast\", \"Northeast\", \"East-Northeast\",\n",
        "            \"East\", \"East-Southeast\", \"Southeast\", \"South-Southeast\",\n",
        "            \"South\", \"South-Southwest\", \"Southwest\", \"West-Southwest\",\n",
        "            \"West\", \"West-Northwest\", \"Northwest\", \"North-Northwest\"\n",
        "        ]\n",
        "        idx = int((deg + 11.25) % 360 / 22.5)\n",
        "        return directions[idx]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 928
        },
        "id": "ANMe8NC_ItkQ",
        "outputId": "5fdccf88-b924-439c-8045-70a3fb644fe8"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Coordinates（(22.981447193790117, 120.222421206433)）information :\n",
            "\n",
            "LOCATION_CONTEXT:\n",
            "  Location information: house\n",
            "  Category: Unknown\n",
            "  Detailed: 151號, 崇善路, 龍山里, 東區, 臺南市, 701, 臺灣\n",
            "\n",
            "WEATHER:\n",
            "  temperature: 29.94\n",
            "  humidity: 79.0\n",
            "  pressure: 1008.0\n",
            "  visibility_m: 10000\n",
            "  wind_speed_m_s: 3.09\n",
            "  wind_deg and direction: West-Southwest(240)\n",
            "  weather_description: broken clouds\n",
            "\n",
            "NDVI:\n",
            "  mean: 78.11111111111111\n",
            "  max: 244.0\n",
            "  min: 0.0\n",
            "  level: High\n",
            "\n",
            "NDWI:\n",
            "  mean: 0.0\n",
            "  max: 0.0\n",
            "  min: 0.0\n",
            "  level: Neutral\n",
            "\n",
            "NDBI:\n",
            "  mean: 44.77777777777778\n",
            "  max: 137.0\n",
            "  min: 0.0\n",
            "  level: Dense\n",
            "\n",
            "AIR_QUALITY:\n",
            "  pm2_5: 4.4\n",
            "  pm10: 6.87\n",
            "  aqi_level: 1\n",
            "\n",
            "GEOMAGNETIC:\n",
            "  elevation_km: 0.00000\n",
            "  declination_deg: -4.37677\n",
            "  declination_sv_deg_per_year: -0.03408\n",
            "  declination_uncertainty_deg: 0.29822\n",
            "  stability: Stable\n",
            "\n",
            "TIME_CONTEXT:\n",
            "  daylight_duration: 13:01:56.097510\n",
            "  weekday: Saturday\n",
            "  moon_phase: Full Moon\n",
            "\n"
          ]
        }
      ],
      "source": [
        "\n",
        "# coordinates = (24.8138, 120.9675) #新竹\n",
        "# coordinates = (47.64515571212685, -122.35766117299868) #西雅图\n",
        "# coordinates = (25.00096552660932, 121.31677758875244) #桃园\n",
        "# coordinates = (25.1368, 121.5064) #北投\n",
        "coordinates = (22.981447193790117, 120.222421206433) #台南\n",
        "\n",
        "daytime = datetime.now().strftime(\"%Y-%m-%dT%H:%M:%S\")\n",
        "\n",
        "geomagnetic_api_key = \"gFE5W\"\n",
        "\n",
        "api = EnvironmentIndexAPI(\n",
        "   ndbi_source = '/content/NDBI.tif',\n",
        "   ndvi_source = '/content/NDVI.tif',\n",
        "   ndwi_source = '/content/NDWI.tif',\n",
        "   geomagnetic_api_key=geomagnetic_api_key\n",
        ")\n",
        "\n",
        "result = api.get_environmental_info(coordinates, daytime, radius=500)\n",
        "\n",
        "print(f\"Coordinates（{coordinates}）information :\\n\")\n",
        "for key, value in result.items():\n",
        "    print(f\"{key.upper()}:\")\n",
        "    if isinstance(value, dict):\n",
        "        for sub_key, sub_value in value.items():\n",
        "            print(f\"  {sub_key}: {sub_value}\")\n",
        "    else:\n",
        "        print(f\"  {value}\")\n",
        "    print()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TV8zaqFbLtEP"
      },
      "source": [
        "Providing Gemini with the patient's real time environmental factors, patient profile and using it to provide suggestions regarding Parkinson's"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "jK8cl5jEIukV",
        "outputId": "2fa7869f-a9e9-482d-a8c5-6bc42255f1d8"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "!pip install -q google-generativeai"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "RKOu4rV0I36v",
        "outputId": "d09f0203-7a8d-48a1-fb9a-4147559f9059"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "import os\n",
        "import google.generativeai as genai\n",
        "import pandas as pd"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "35SgVl8_I6U-",
        "outputId": "c09e1a91-86ce-4ca3-f377-722d913501c8"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# 1. define gemini api key\n",
        "GOOGLE_API_KEY = \"API Key\"\n",
        "genai.configure(api_key=GOOGLE_API_KEY)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 17
        },
        "id": "Wck2oBwZI79N",
        "outputId": "2b07b4e5-7363-4a50-b3da-cc16231c2f38"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# 2. define the prompt\n",
        "def build_prompt(profile, environment):\n",
        "    return f\"\"\"\n",
        "You are a rehabilitation medicine expert specializing in early intervention for neurodegenerative diseases, especially Parkinson’s disease.\n",
        "\n",
        "Your task is to provide a short, practical, and scientifically sound recommendation for the individual below, focused only on:\n",
        "- Natural environment (e.g., weather, air quality, vegetation)\n",
        "- Daily mobility or outdoor routines\n",
        "\n",
        "Please consider that the individual may be at risk of developing Parkinson's disease, showing early signs such as tremor, constipation, reduced sense of smell, or REM sleep behavior disorder.\n",
        "\n",
        "Your recommendation should be grounded in scientific evidence and may include:\n",
        "- Encouragement of **moderate-intensity exercise** such as walking, Tai Chi, or balance training (e.g., 150 minutes/week)\n",
        "- Consideration of **environmental stressors** like heat, humidity, or air quality that may impact mobility or autonomic regulation\n",
        "- Suggestions for **outdoor routines** that support physical activity, mood, and circadian rhythm (e.g., morning light exposure, green spaces)\n",
        "- Supportive strategies aligned with early PD management such as staying hydrated, avoiding prolonged sedentary time, and using shaded or low-traffic routes\n",
        "\n",
        "Do not recommend medical treatments. Focus on actionable lifestyle/environmental suggestions that promote safety, comfort, and health.\n",
        "\n",
        "[Personal Profile]:\n",
        "{profile}\n",
        "\n",
        "[Environmental Description]:\n",
        "{environment}\n",
        "\"\"\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tGWF4QCYJ6nC"
      },
      "source": [
        "Generate an example recommendation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 412
        },
        "id": "jwfgNcvMJAiF",
        "outputId": "904f1169-1f3d-4da0-f55a-cf5414728d5a"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "            <style>\n",
              "                .geemap-dark {\n",
              "                    --jp-widgets-color: white;\n",
              "                    --jp-widgets-label-color: white;\n",
              "                    --jp-ui-font-color1: white;\n",
              "                    --jp-layout-color2: #454545;\n",
              "                    background-color: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-dark .jupyter-button {\n",
              "                    --jp-layout-color3: #383838;\n",
              "                }\n",
              "\n",
              "                .geemap-colab {\n",
              "                    background-color: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "\n",
              "                .geemap-colab .jupyter-button {\n",
              "                    --jp-layout-color3: var(--colab-primary-surface-color, white);\n",
              "                }\n",
              "            </style>\n",
              "            "
            ],
            "text/plain": [
              "<IPython.core.display.HTML object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Example Recommendation Output:\n",
            "Okay, based on the provided information, here's a short, practical recommendation focusing on the natural environment and daily mobility for this 62-year-old male in Hsinchu City, Taiwan:\n",
            "\n",
            "**Recommendation:**\n",
            "\n",
            "Given your risk factors for Parkinson's disease, it's crucial to proactively support your brain health and mobility. Focus on incorporating structured outdoor activity, taking into account the local environment:\n",
            "\n",
            "1.  **Prioritize Morning Walks in Green Spaces:** Aim for a 30-45 minute brisk walk in nearby parks most days of the week. The high NDVI suggests access to beneficial green spaces. Morning light exposure is vital for regulating your sleep-wake cycle (addressing the short sleep duration) and can improve mood.\n",
            "\n",
            "2.  **Manage Heat and Air Quality:** With the current temperature (31°C) and humidity (77%), and moderate air quality (AQI level 3), avoid strenuous activity during the hottest part of the day. Walk in the early morning or late afternoon when temperatures are milder. On days with higher PM2.5 readings, opt for indoor exercise or shorter walks in areas with more vegetation, which can help filter the air. Stay well hydrated, especially during and after your walks.\n",
            "\n",
            "3.  **Incorporate Tai Chi or Balance Exercises Outdoors:** Consider joining a Tai Chi class in a local park. The slow, deliberate movements can improve balance, coordination, and flexibility, which are beneficial given the potential for tremor and balance issues associated with early PD. Tai Chi is particularly useful as the progression of PD can lead to postural instability.\n",
            "\n",
            "4.  **Plan Accessible and Safe Routes:** Choose walking routes that are well-maintained, relatively flat, and have shaded areas. This is especially important given the high humidity. Avoid busy roads to minimize exposure to air pollution. Utilize low-traffic routes within parks or residential areas.\n",
            "\n",
            "5.  **Address Constipation through Activity and Hydration:** Regular physical activity, especially walking, can help improve bowel function. Continue to prioritize hydration throughout the day, as adequate water intake is crucial for managing constipation.\n",
            "\n",
            "**Rationale:**\n",
            "\n",
            "These recommendations are designed to increase physical activity to meet the recommended 150 minutes of moderate-intensity exercise per week, focusing on activities proven to be beneficial in Parkinson's disease prevention and management. The recommendations address the environmental factors of heat, humidity, and air quality to ensure safety and comfort. The emphasis on morning light exposure aims to improve sleep quality and circadian rhythm, while utilizing green spaces provides potential benefits for mood and cognitive function. By addressing the early symptoms like constipation through exercise and hydration, we aim to improve quality of life and potentially slow disease progression.\n",
            "\n"
          ]
        }
      ],
      "source": [
        "# 3. Use gemini to provide advice\n",
        "def generate_recommendation(profile, environment):\n",
        "    prompt = build_prompt(profile, environment)\n",
        "    model = genai.GenerativeModel('gemini-2.0-flash')\n",
        "    response = model.generate_content(prompt)\n",
        "    return response.text\n",
        "\n",
        "# 4. example usage\n",
        "example_profile = '''\n",
        "AGE: 62\n",
        "GENDER: Male\n",
        "FREQUENT LOCATIONS: Nearby parks, neighborhood supermarket\n",
        "FAMILY HISTORY: Father diagnosed with Parkinson’s disease\n",
        "LIFESTYLE: Frequently stays up late, low physical activity, chronic constipation in recent years\n",
        "SYMPTOM SCORE:\n",
        "- Tremor: 1/5\n",
        "- Constipation: 4/5\n",
        "- Reduced sense of smell: 2/5\n",
        "- REM sleep behavior disorder: 3/5\n",
        "RISK LEVEL: Moderately high (Total Score: 10)\n",
        "WEARABLE DATA:\n",
        "- Average daily steps: < 3000\n",
        "- Average sleep: 5.5 hours/night\n",
        "'''\n",
        "example_environment = '''\n",
        "LOCATION CONTEXT:\n",
        "- Secondary urban road in Hsinchu City, Taiwan (Dongda Rd. Sec. 2, Shuǐtián Lǐ)\n",
        "\n",
        "\n",
        "WEATHER:\n",
        "- Temperature: 31.08°C\n",
        "- Humidity: 77%\n",
        "- Atmospheric Pressure: 1004 hPa\n",
        "- Visibility: 10,000 meters\n",
        "- Wind: 0.89 m/s, Northwest (310°)\n",
        "- Sky Condition: Few clouds\n",
        "\n",
        "\n",
        "VEGETATION INDEX (NDVI): High\n",
        "WATER INDEX (NDWI): Neutral\n",
        "BUILT-UP INDEX (NDBI): Dense\n",
        "\n",
        "\n",
        "AIR QUALITY:\n",
        "- PM2.5: 37.77 µg/m³\n",
        "- PM10: 48.85 µg/m³\n",
        "- AQI Level: 3 (Moderate)\n",
        "'''\n",
        "\n",
        "\n",
        "print(\"Example Recommendation Output:\")\n",
        "print(generate_recommendation(example_profile, example_environment))\n",
        "\n",
        "# 5. if the data is large use csv\n",
        "def batch_generate_from_csv(csv_path):\n",
        "    df = pd.read_csv(csv_path)\n",
        "    for idx, row in df.iterrows():\n",
        "        print(f\"\\n👤 Recommendation for individual #{idx+1}:\")\n",
        "        print(generate_recommendation(row['profile'], row['environment']))\n"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
